package controllers

import (
	"encoding/json"
	"errors"
	"gitee.com/lzqysoft/ims/models"
	"strings"

	"github.com/astaxie/beego"
	"time"
)

// ImsProjectController operations for ImsProject
type ImsProjectController struct {
	CommonController
}

// URLMapping ...
func (c *ImsProjectController) URLMapping() {
	c.Mapping("Post", c.Post)
	c.Mapping("GetOne", c.GetOne)
	c.Mapping("GetAll", c.GetAll)
	c.Mapping("Put", c.Put)
	c.Mapping("Delete", c.Delete)
	c.Mapping("GetProject", c.GetProject)
	c.Mapping("DeleteImsProjectList", c.DeleteImsProjectList)
	c.Mapping("Query", c.Query)
	c.Mapping("ProjectApprove", c.ProjectApprove)
	c.Mapping("QueryImsProjectByImsProjectFlow", c.QueryImsProjectByImsProjectFlow)
	c.Mapping("QueryImsProjectById", c.QueryImsProjectById)
	c.Mapping("UpdateImsProject", c.UpdateImsProject)
	c.Mapping("QueryLiegeImsProject", c.QueryLiegeImsProject)
	c.Mapping("QueryLegeProject", c.QueryLegeProject)
	c.Mapping("QueryBudgetByProject", c.QueryBudgetByProject)
	c.Mapping("QueryUsedByProject", c.QueryUsedByProject)
	c.Mapping("CreateImsUsed", c.CreateImsUsed)
	c.Mapping("UpdateImsUsed", c.UpdateImsUsed)
	c.Mapping("DeleteImsUsedList", c.DeleteImsUsedList)
	c.Mapping("QueryImsProjectByProjectFlow", c.QueryImsProjectByProjectFlow)
	c.Mapping("DownloadDocx", c.DownloadDocx)
	c.Mapping("GetProjectBySequence", c.GetProjectBySequence)
	c.Mapping("SetLevel", c.SetLevel)
	c.Mapping("ImsProjectChange", c.ImsProjectChange)

}

// Post ...
// @Title Post
// @Description create ImsProject
// @Param	body		body 	models.ImsProject	true		"body for ImsProject content"
// @Success 201 {int} models.ImsProject
// @Failure 403 body is empty
// @router / [post]
func (c *ImsProjectController) Post() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	//beego.Debug(string(tdata))
	m := models.NewImsProject()
	if err = json.Unmarshal(tdata, m); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	m.No = models.GetProjectNo(m.SequenceId, user.Organization.Code, m.ProjectType)
	m.CId = user.Id
	m.Creater = user.Abbr
	m.UId = user.Id
	m.Updater = user.Abbr
	m.OrgId = user.Organization.Id
	m.DeptId = user.Dept[0].Id
	beego.Debug(m.ImsBudget)
	if _, err = models.AddImsProject(m); err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	//

	c.RetSuccess(nil)
}

// GetOne ...
// @Title Get One
// @Description get ImsProject by id
// @Param	id		path 	string	true		"The key for staticblock"
// @Success 200 {object} models.ImsProject
// @Failure 403 :id is empty
// @router /:id [get]
func (c *ImsProjectController) GetOne() {
	idStr := c.Ctx.Input.Param(":id")
	//id, _ := strconv.Atoi(idStr)
	v, err := models.GetImsProjectById(idStr)
	if err != nil {
		c.Data["json"] = err.Error()
		beego.Debug(err)
		c.RetError(ErrInputData)
	} else {
		c.RetSuccess(v)
	}
	//c.ServeJSON()
}

// GetAll ...
// @Title Get All
// @Description get ImsProject
// @Param	query	query	string	false	"Filter. e.g. col1:v1,col2:v2 ..."
// @Param	fields	query	string	false	"Fields returned. e.g. col1,col2 ..."
// @Param	sortby	query	string	false	"Sorted-by fields. e.g. col1,col2 ..."
// @Param	order	query	string	false	"Order corresponding to each sortby field, if single value, apply to all sortby fields. e.g. desc,asc ..."
// @Param	limit	query	string	false	"Limit the size of result set. Must be an integer"
// @Param	offset	query	string	false	"Start position of result set. Must be an integer"
// @Success 200 {object} models.ImsProject
// @Failure 403
// @router / [get]
func (c *ImsProjectController) GetAll() {
	var fields []string
	var sortby []string
	var order []string
	var query = make(map[string]string)
	var limit int64 = 10
	var offset int64

	// fields: col1,col2,entity.col3
	if v := c.GetString("fields"); v != "" {
		fields = strings.Split(v, ",")
	}
	// limit: 10 (default is 10)
	if v, err := c.GetInt64("limit"); err == nil {
		limit = v
	}
	// offset: 0 (default is 0)
	if v, err := c.GetInt64("offset"); err == nil {
		offset = v
	}
	// sortby: col1,col2
	if v := c.GetString("sortby"); v != "" {
		sortby = strings.Split(v, ",")
	}
	// order: desc,asc
	if v := c.GetString("order"); v != "" {
		order = strings.Split(v, ",")
	}
	// query: k:v,k:v
	if v := c.GetString("query"); v != "" {
		for _, cond := range strings.Split(v, ",") {
			kv := strings.SplitN(cond, ":", 2)
			if len(kv) != 2 {
				c.Data["json"] = errors.New("Error: invalid query key/value pair")
				c.ServeJSON()
				return
			}
			k, v := kv[0], kv[1]
			query[k] = v
		}
	}

	l, err := models.GetAllImsProject(query, fields, sortby, order, offset, limit)
	if err != nil {
		c.Data["json"] = err.Error()
	} else {
		c.Data["json"] = l
	}
	c.ServeJSON()
}

// Put ...
// @Title Put
// @Description update the ImsProject
// @Param	id		path 	string	true		"The id you want to update"
// @Param	body		body 	models.ImsProject	true		"body for ImsProject content"
// @Success 200 {object} models.ImsProject
// @Failure 403 :id is not int
// @router /:id [put]
func (c *ImsProjectController) Put() {
	idStr := c.Ctx.Input.Param(":id")
	//id, _ := strconv.Atoi(idStr)
	v := models.ImsProject{Id: idStr}
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &v); err == nil {
		if err := models.UpdateImsProjectById(&v); err == nil {
			c.Data["json"] = "OK"
		} else {
			c.Data["json"] = err.Error()
		}
	} else {
		c.Data["json"] = err.Error()
	}
	c.ServeJSON()
}

// Delete ...
// @Title Delete
// @Description delete the ImsProject
// @Param	id		path 	string	true		"The id you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 id is empty
// @router /:id [delete]
func (c *ImsProjectController) Delete() {
	idStr := c.Ctx.Input.Param(":id")
	//id, _ := strconv.Atoi(idStr)
	if err := models.DeleteImsProject(idStr); err == nil {
		c.Data["json"] = "OK"
	} else {
		c.Data["json"] = err.Error()
	}
	c.ServeJSON()
}

// GetProject ...
// @Title GetProject
// @Description GetProject
// @Success 200 {Array} []models.ImsProject
// @Failure 403
// @router /GetProject [get]
func (c *ImsProjectController) GetProject() {
	user := c.User
	if res, err := models.GetImsProjectsByRoleType(user); err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	} else {
		c.RetSuccess(res)
	}
}

// DeleteImsProjectList ...
// @Title DeleteImsProjectList
// @DescriptionDeleteImsProjectList
// @Param	bodys		path 	[]models.ImsProject	 true		"The ImsProject you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 input data error
// @router /DeleteImsProjectList [post]
func (c *ImsProjectController) DeleteImsProjectList() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var l []models.ImsProject
	if err = json.Unmarshal(tdata, &l); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	if err = models.SoftDeleteImsProject(l, user); err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(nil)
}

// Query ...
// @Title Query
// @Query
// @Param	QueryParams		path 	QueryParams	 true		"QueryParams"
// @Success 200 {string} delete success!
// @Failure 403 input data error
// @router /Query [post]
func (c *ImsProjectController) Query() {
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var params QueryParams
	if err = json.Unmarshal(tdata, &params); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	l, err := models.GetAllImsProject(params.Query, params.Fields, params.SortBy, params.Order,
		params.Page, params.PageSize)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(l)
}

// ProjectApprove ...
// @Title ProjectApprove
// @Param	ImsProject		path 	ImsProject	 true		"ImsProject"
// @Success 200 {string} approve success!
// @Failure 403 input data error
// @router /ProjectApprove [post]
func (c *ImsProjectController) ProjectApprove() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var m models.ImsProject
	if err = json.Unmarshal(tdata, &m); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	// 生成 projecte_flow

	//
	if err = models.StartImsProjectFlow(m, 0, user); err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(nil)
}

// QueryImsProjectByImsProjectFlow ...
// @Title QueryImsProjectByImsProjectFlow
// @Param	QueryImsProjectByImsProjectFlow  path 	ImsProject	 true		"ImsProjectFlow"
// @Success 200 {string} query success!
// @Failure 403 input data error
// @router /QueryImsProjectByImsProjectFlow [post]
func (c *ImsProjectController) QueryImsProjectByImsProjectFlow() {
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var m models.ImsProject
	if err = json.Unmarshal(tdata, &m); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	beego.Debug(m.Id)
	v, err := models.GetImsProjectById(m.Id)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	c.RetSuccess(v)
}

// QueryImsProjectByProjectFlow ...
// @Title QueryImsProjectByProjectFlow
// @Param	QueryImsProjectByProjectFlow  path 	ImsProject	 true		"ImsProjectFlow"
// @Success 200 {string} query success!
// @Failure 403 input data error
// @router /QueryImsProjectByProjectFlow [post]
func (c *ImsProjectController) QueryImsProjectByProjectFlow() {
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var m models.ImsProjectFlow
	if err = json.Unmarshal(tdata, &m); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	v, err := models.GetImsProjectById(m.ProjectId)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	c.RetSuccess(v)
}

// QueryImsProjectById ...
// @Title QueryImsProjectById
// @Param	QueryImsProjectById  path 	ImsProject	 true		"ImsProjectFlow"
// @Success 200 {string} query success!
// @Failure 403 id data error
// @router /QueryImsProjectById [post]
func (c *ImsProjectController) QueryImsProjectById() {
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var params QueryParams
	if err = json.Unmarshal(tdata, &params); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	pid, ok := params.Query["Id"]
	if !ok {
		beego.Debug("no id params")
		c.RetError(ErrInputData)
	}
	if m, err := models.GetImsProjectById(pid); err == nil {
		//beego.Debug(m.ImsBudget)
		c.RetSuccess(m)
	} else {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
}

// UpdateImsProject ...
// @UpdateImsProject
// @Description UpdateImsProject
// @Param	body		body 	models.ImsProject	true		"body for ImsProject content"
// @Success 200 {object} models.ImsProject
// @Failure 403 :id is not int
// @router /UpdateImsProject [post]
func (c *ImsProjectController) UpdateImsProject() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var m models.ImsProject
	if err := json.Unmarshal(tdata, &m); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	m.Utime, m.Updater = time.Now(), user.Abbr
	if err := models.UpdateImsProjectRel(&m); err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(nil)
}

// SetLevel ...
// @SetLevel
// @Description SetLevel
// @Param	body		body 	models.ImsProject	true		"body for ImsProject content"
// @Success 200 {object} models.ImsProject
// @Failure 403 :id is not int
// @router /SetLevel [post]
func (c *ImsProjectController) SetLevel() {
	user := c.User
	type SetLevel struct {
		Id         string
		Level      int
		ProvinceNo string
	}
	params := &SetLevel{}
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	if err = json.Unmarshal(tdata, params); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	v, _ := models.GetImsProjectById(params.Id)
	v.Level = params.Level
	v.ProvinceNo = params.ProvinceNo
	v.Utime, v.Updater, v.UId = time.Now(), user.Abbr, user.Id
	if err = models.UpdateImsProjectById(v); err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(nil)

}

// QueryLiegeImsProject ...
// @QueryLiegeImsProject
// @Description QueryLiegeImsProject
// @Success 200 {object} models.ImsProject
// @router /QueryLiegeImsProject [get]
func (c *ImsProjectController) QueryLiegeImsProject() {
	user := c.User
	l, err := models.QueryLegalProject(user)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(l)
}

// QueryLegeProject ...
// @QueryLegeProject
// @Description QueryLegeProject
// @Success 200 {object} models.ImsProject
// @router /QueryLegeProject/:id [get]
func (c *ImsProjectController) QueryLegeProject() {
	user := c.User
	sequenceId := c.Ctx.Input.Param(":id")
	if sequenceId != "" {
		if l, err := models.QueryLegeProject(user, sequenceId); err != nil {
			beego.Debug(err)
			c.RetError(ErrDatabase)
		} else {
			c.RetSuccess(l)
		}
	} else {
		c.RetError(ErrInputData)
	}

}

// QueryBudgetByProject ...
// @QueryBudgetByProject
// @Description QueryBudgetByProject
// @Success 200 {object} models.Budget
// @router /QueryBudgetByProject [post]
func (c *ImsProjectController) QueryBudgetByProject() {
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var params QueryParams
	if err = json.Unmarshal(tdata, &params); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	pid, ok := params.Query["ProjectId"]
	if !ok {
		beego.Debug("no id params")
		c.RetError(ErrInputData)
	}
	l, err := models.GetBudgetByProjectId(pid)
	if err != nil {
		c.RetError(ErrInputData)
	}
	c.RetSuccess(l)
}

// QueryUsedByProject ...
// @QueryUsedByProject
// @Description QueryBudgetByProject
// @Success 200 {object} models.Used
// @router /QueryUsedByProject [post]
func (c *ImsProjectController) QueryUsedByProject() {
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var params QueryParams
	if err = json.Unmarshal(tdata, &params); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	pid, ok := params.Query["BudgetId"]
	if !ok {
		beego.Debug("no id params")
		c.RetError(ErrInputData)
	}
	l, err := models.GetUsedByBudgetId(pid)
	if err != nil {
		c.RetError(ErrInputData)
	}
	c.RetSuccess(l)
}

// CreateImsUsed ...
// @CreateImsUsed
// @Description CreateImsUsed
// @Success 200 {object} null
// @router /CreateImsUsed [post]
func (c *ImsProjectController) CreateImsUsed() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var used models.ImsUsed
	if err = json.Unmarshal(tdata, &used); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	used.Ctime, used.Creater = time.Now(), user.Abbr
	if _, err := models.AddImsUsed(&used); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	c.RetSuccess(nil)
}

// UpdateImsUsed ...
// @UpdateImsUsed
// @Description UpdateImsUsed
// @Success 200 {object} null
// @router /UpdateImsUsed [post]
func (c *ImsProjectController) UpdateImsUsed() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var used models.ImsUsed
	if err = json.Unmarshal(tdata, &used); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	used.Ctime, used.Creater = time.Now(), user.Abbr
	if err := models.UpdateImsUsedById(&used); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	c.RetSuccess(nil)
}

// DeleteImsUsedList ...
// @Title DeleteImsUsedList
// @Description DeleteImsUsedList
// @Param	bodys		path 	[]models.ImsProject	 true		"The ImsUsed you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 input data error
// @router /DeleteImsUsedList [post]
func (c *ImsProjectController) DeleteImsUsedList() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	var l []models.ImsUsed
	if err = json.Unmarshal(tdata, &l); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	if err = models.SoftDeleteImsUsed(l, user); err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	c.RetSuccess(nil)
}

// DownloadDocx ...
// @Title DownloadDocx
// @Description DownloadDocx
// @Param	id		path 	string	 true		"The project you want to download"
// @Success 200 {string} get success!
// @Failure 403 input data error
// @router /DownloadDocx [post]
func (c *ImsProjectController) DownloadDocx() {
	type dparams struct {
		Id string
	}
	params := &dparams{}
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		c.RetError(ErrToken)
	}
	//beego.Debug(tdata)
	if err = json.Unmarshal(tdata, &params); err != nil {
		c.RetError(ErrInputData)
	}
	fid, err := models.GetZipUrl(params.Id)
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrFds)
	}
	c.RetSuccess(fid)
}

// GetProjectBySequence ...
// @Title GetProjectBySequence
// @Description GetProjectBySequence
// @Success 200 {string} get success!
// @Failure 403 input data error
// @router /GetProjectBySequence/:id [get]
func (c *ImsProjectController) GetProjectBySequence() {
	user := c.User
	sequenceId := c.Ctx.Input.Param(":id")
	if sequenceId != "" {
		l, err := models.GetImsProjectBySequenceAndUser(sequenceId, user)
		if err != nil {
			beego.Debug(err)
			c.RetError(ErrDatabase.SetMessage(err.Error()))
		} else {
			c.RetSuccess(l)
		}
	} else {
		c.RetError(ErrInputData)
	}
}

// QueryImsProjectNoRel ...
// @Title QueryImsProjectNoRel
// @Description QueryImsProjectNoRel
// @Success 200 {string} get success!
// @Failure 403 input data error
// @router /QueryImsProjectNoRel/:id [get]
func (c *ImsProjectController) QueryImsProjectNoRel() {
	//user := c.User
	projectId := c.Ctx.Input.Param(":id")
	if projectId != "" {
		l, err := models.GetImsProjectByIdNoRel(projectId)
		if err != nil {
			beego.Debug(err)
			c.RetError(ErrDatabase.SetMessage(err.Error()))
		} else {
			c.RetSuccess(l)
		}
	} else {
		c.RetError(ErrInputData)
	}
}

// ImsProjectChange ...
// @Title ImsProjectChange
// @Description change ImsProject
// @Param	body		body 	models.ImsProject	true		"body for ImsProject content"
// @Success 201 {int} models.ImsProject
// @Failure 403 body is empty
// @router /ImsProjectChange [post]
func (c *ImsProjectController) ImsProjectChange() {
	user := c.User
	tdata, err := c.AesDecodeToByte(c.GetString("tdata"))
	if err != nil {
		beego.Debug(err)
		c.RetError(ErrToken)
	}
	//beego.Debug(string(tdata))
	m := models.NewImsProject()
	if err = json.Unmarshal(tdata, m); err != nil {
		beego.Debug(err)
		c.RetError(ErrInputData)
	}
	//m.No = models.GetProjectNo(m.SequenceId, user.Organization.Code, m.ProjectType)
	//m.CId = user.Id
	m.Creater = user.Abbr
	//m.UId = user.Id
	m.Updater = user.Abbr
	//m.OrgId = user.Organization.Id
	//m.DeptId = user.Dept[0].Id
	beego.Debug(m.ImsBudget)
	if _, err = models.AddImsProject(m); err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}
	// fms commit
	if err = models.StartImsProjectFlow(*m, 3, user); err != nil {
		beego.Debug(err)
		c.RetError(ErrDatabase)
	}

	c.RetSuccess(nil)
}

// ExportXls ...
// @Title ExportXls
// @Description ExportXls
// @Param	 id		projectid 	[]string 	    true		"array of project's id"
// @Success 201 {int} models.ImsProject
// @Failure 403 body is empty
// @router /ExportXlsx [post]
func (c *ImsProjectController) ExportXlsx() {

}
